#pragma once
#include "stdafx.h"

//https://github.com/Mooophy/Cpp-Primer/blob/master/ch12/README.md

void process(std::shared_ptr<int> ptr)
{
	std::cout << "inside the process function:" << ptr.use_count() << "\n";
}


int dy_test1()
{

	std::shared_ptr<int> p(new int(42));
	process(std::shared_ptr<int>(p));

	/**
	* codes below shows how the reference count change.
	*/
	std::cout << p.use_count() << "\n";
	auto q = p;
	std::cout << p.use_count() << "\n";
	std::cout << "the int p now points to is:" << *p << "\n";
	return 0;
}

int dy_test2()
{
	auto p = new int(1);
	auto sp = make_shared<int>();
	process(sp);
	//process(new int());
	//process(p);
	process(shared_ptr<int>(p));

	cout << *p << endl;

	return 0;
}

void mydel(int* p)
{
	cout << "mydel have been run" << endl;
	delete p;
	p = nullptr;
}

void throw_test()
{
	throw runtime_error("a error");
}


void dy_test3()
{
	int* a = new int(5);
	shared_ptr<int> p(a, mydel);
	throw_test();
	cout << "It cannot run" << endl;
}

void dy_test4()
{
	shared_ptr<int> p(new int(1024));
	auto q = p;
	cout << "p count:" << p.use_count() <<" " << *p << endl;
	cout << "q count:" << q.use_count() << " " << *q << endl;
	p.reset(new int(5));
	cout << "p count:" << p.use_count() << " " << *p << endl;
	cout << "q count:" << q.use_count() << " " << *q << endl;
}

auto unique_test()
{
	int *b = new int(4);
	unique_ptr<int> u(b);
	return u;
}

void dy_test5()
{
	auto u = unique_test();
	cout << *u << endl;
}


void dy_test6()
{
	unique_ptr<string> p1(new string("hello"));

	//unique_ptr<string> p2(p1);

	//unique_ptr<string> p3 = p1;
}

void dy_test7()
{
	auto p = make_shared<int>(42);
	weak_ptr<int> w = p;
	cout << p.use_count() << endl;
	cout << w.use_count() << endl;
	shared_ptr<int> p2 = w.lock();
	cout << p.use_count() << endl;
	cout << p2.use_count() << endl;
}

void mystrlen(const char *str)
{
	cout << str << endl;
}


void dy_test8()
{
	//mystrlen("hello " "world" "dds");
	string s1 = "hello";
	string s2 = "world";
	unique_ptr<char[]> ps(new char[s1.size() + s2.size()]);
	size_t pos = 0;
	for (auto c: s1) {
		ps[pos++] = c;
	}
	for (auto c : s2) {
		ps[pos++] = c;
	}
	for (size_t i = 0; i != 10; ++i) {
		cout << ps[i];
	}
	cout << endl;
}

void dy_test9()
{
	allocator<string> alloc;
	auto p = alloc.allocate(10);
	auto q = p;
	for (int i = 0; i < 10; ++i) {
		alloc.construct(q++, i+1,'d');
		cout << p[i] << endl;
	}
	while (q != p) {
		alloc.destroy(--q);
	}
	for (int i = 0; i < 10; ++i) {
		alloc.construct(q++, i + 1, 'w');
		cout << p[i] << endl;
	}
	while (q != p) {
		alloc.destroy(--q);
	}
	alloc.deallocate(p, 10);
}


//void dy_test10(void)
//{
//	vector<int> v{ 1,2,3,4 };
//	for (auto d : v) {
//		cout << d << endl;
//	}
//	allocator<int> alloc;
//	auto p = alloc.allocate(v.size() * 2);
//	auto q = uninitialized_copy(v.begin(), v.end(), p);
//	uninitialized_fill_n(q, v.size(), 22);
//	for (int i = 0; i < v.size() * 2; ++i) {
//		cout << p[i] << " ";
//	}
//	cout << endl;
//
//
//}